#include <iostream>
#include "EnvironmentMap.h"
#include <stdexcept>
#include <DXUT.h>


e3d::EnvironmentMap::EnvironmentMap( ID3D10Device* device, ID3D10Effect* effect )
:	m_ndcBuffer( NULL ), 
	m_ndcLayout( NULL ),
	m_device( device ),
	m_effect( effect )
{
	//------------------------------------------------
	// Load the environment map texture
	//------------------------------------------------
	m_pCubeMapVariable = m_effect->GetVariableByName( "cubeMap" )->AsShaderResource();
	D3DX10CreateShaderResourceViewFromFile( m_device, L"textures/SouthernSea.dds", NULL, NULL, &m_pCubeMapRV, NULL );
	m_pCubeMapVariable->SetResource( m_pCubeMapRV );

	//------------------------------------------------
	// Create vertex buffer for environment mapping
	//------------------------------------------------
	D3DXVECTOR4 ndcBuffer[6] =
	{
		D3DXVECTOR4( -1.0f, 1.0f, 0.999999f, 1.0f ),
		D3DXVECTOR4( 1.0f, 1.0f, 0.999999f, 1.0f  ),
		D3DXVECTOR4( -1.0f, -1.0f, 0.999999f, 1.0f  ),
		D3DXVECTOR4( -1.0f, -1.0f, 0.999999f, 1.0f  ),
		D3DXVECTOR4( 1.0f, 1.0f, 0.999999f, 1.0f  ),
		D3DXVECTOR4( 1.0f, -1.0f, 0.999999f, 1.0f  )
	};

	D3D10_INPUT_ELEMENT_DESC ndcInputDesc[] = 
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_VERTEX_DATA, 0 }
	};
	unsigned int numElements = sizeof(ndcInputDesc) / sizeof(ndcInputDesc[0]);

	D3D10_BUFFER_DESC ndcDesc;
	ndcDesc.Usage = D3D10_USAGE_DEFAULT;
	ndcDesc.ByteWidth = sizeof( D3DXVECTOR4 ) * 6;
	ndcDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
	ndcDesc.CPUAccessFlags = 0;
	ndcDesc.MiscFlags = 0;
	D3D10_SUBRESOURCE_DATA ndcInitData;
	ndcInitData.pSysMem = ndcBuffer;
	if( FAILED( m_device->CreateBuffer( &ndcDesc, &ndcInitData, &m_ndcBuffer ) ) )
		throw std::logic_error("Could not create input layout");

	ID3D10EffectTechnique* tech = effect->GetTechniqueByName("PhongShading");
	ID3D10EffectPass* cmPass = tech->GetPassByName( "envmap" );

	D3D10_PASS_DESC cmPassDesc;
	cmPass->GetDesc( &cmPassDesc );
	if( FAILED( m_device->CreateInputLayout( ndcInputDesc, numElements, cmPassDesc.pIAInputSignature, cmPassDesc.IAInputSignatureSize, &m_ndcLayout)))
		throw std::logic_error("Could not create input layout");
}

e3d::EnvironmentMap::~EnvironmentMap(void)
{
	// Unbind texture resource view
	ID3D10ShaderResourceView * const nullRes[1] = {NULL};
	m_device->PSSetShaderResources( 0, 1, nullRes );

	SAFE_RELEASE( m_ndcLayout );
	SAFE_RELEASE( m_ndcBuffer );
	SAFE_RELEASE( m_pCubeMapRV );
}

void e3d::EnvironmentMap::render( ID3D10EffectTechnique* tech, const D3DXVECTOR3* camPos )
{
	unsigned int stride = sizeof( D3DXVECTOR4 );
	unsigned int offset = 0;

	m_device->IASetInputLayout( m_ndcLayout );
	m_device->IASetVertexBuffers( 0, 1, &m_ndcBuffer, &stride, &offset );
	m_device->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
	
	tech->GetPassByName("envmap")->Apply(0);

	m_device->Draw( 6, 0 );
}
																												 

																												 